package com.asm.service;

import com.asm.dto.PageResult;
import com.asm.entity.sys.District;
import com.asm.repository.DistrictRepository;
import com.asm.util.SnowflakeIdWorker;
import com.asm.vo.sys.DistrictVo;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 功能描述
 *
 * @param * @param null
 * @author Tanzujie
 * @date 2019-07-10
 * @return
 */
@Service
@Slf4j
public class DistrictService {

    @Resource
    private DistrictRepository districtRepository;

    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;

    /**
     * 获取省市区列表
     *
     * @param page 分页
     * @return 省市区列表
     */
    private List<DistrictVo> getDistrictVoList(Page<District> page) {
        List<DistrictVo> list = new ArrayList<>();
        for (District district : page.getContent()) {
            DistrictVo districtVo = new DistrictVo();
            BeanUtils.copyProperties(district, districtVo);
            list.add(districtVo);
        }
        return list;
    }

    /**
     * 获取数据库中所有地区的省份
     *
     * @return 省份列表
     */
    public List<String> getAllProvinces() {
        return districtRepository.findProvinces();
    }

    /**
     * 获取数据库中所有地区的城市
     *
     * @param province 省份
     * @return 省份列表
     */
    public List<String> getAllCitiesByProvince(String province) {
        return districtRepository.findCitiesByProvinceAndIsDel(province);
    }

    /**
     * 获取数据库中所有地区的地区
     *
     * @param city 城市
     * @return 省份列表
     */
    public List<String> getAllDistrictsByCity(String city) {
        return districtRepository.findDistrictsByCityAndIsDel(city);
    }

    /**
     * 根据省份、城市和地区查询districtId
     *
     * @param province 省份
     * @param city     城市
     * @param district 地区
     * @return 列表
     */
    public List<Long> getDistrictIds(String province, String city, String district) {
        List<District> temp = districtRepository.findByProvinceAndCityAndDistrictAndIsDel(province, city, district, false);
        List<Long> list = new ArrayList<>();
        for (District d : temp) {
            list.add(d.getId());
        }
        return list;
    }

    /**
     * 分页查询所有省市区
     *
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 省市区
     */
    public PageResult<DistrictVo> findAllDistricts(Integer pageNumber, Integer pageSize) {
        Page<District> page = districtRepository.findAll(PageRequest.of(pageNumber, pageSize));
        return new PageResult<DistrictVo>(pageNumber, pageSize, page.getTotalPages(), getDistrictVoList(page));
    }

    /**
     * 根据id查询省市区
     *
     * @param id 省市区编号
     * @return 省市区
     */
    public DistrictVo findDistrictById(Long id) {
        District district = districtRepository.findDistinctById(id);
        DistrictVo districtVo = new DistrictVo();
        BeanUtils.copyProperties(district, districtVo);
        return districtVo;
    }

    /**
     * 根据城市分页查询省市区
     *
     * @param city       城市
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 省市区
     */
    public PageResult<DistrictVo> findDistrictByCity(String city, Integer pageNumber, Integer pageSize) {
        Pageable page = PageRequest.of(pageNumber, pageSize);
        Page<District> districts = districtRepository.findByCityAndIsDel(city, false, page);
        return new PageResult<>(pageNumber, pageSize, districts.getTotalPages(), getDistrictVoList(districts));
    }

    /**
     * 添加省市区
     *
     * @param districtVo 省市区对象
     * @return 省市区编号
     */
    @Transactional(rollbackFor = Exception.class)
    public Long addDistrict(DistrictVo districtVo) {
        District district = new District();
        BeanUtils.copyProperties(districtVo, district);
        district.setId(snowflakeIdWorker.nextId());
        district.setCreateAt(new Date());
        district.setCreateBy(1L);
        district.setUpdateAt(new Date());
        district.setUpdateBy(1L);
        districtRepository.save(district);
        return district.getId();
    }

    /**
     * 更新省市区
     *
     * @param districtVo 省市区对象
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateDistrict(DistrictVo districtVo) {
        District district = districtRepository.findById(districtVo.getId()).get();
        BeanUtils.copyProperties(districtVo, district);
        district.setUpdateBy(1L);
        district.setUpdateAt(new Date());
        districtRepository.save(district);
    }

    /**
     * 根据Id删除省市区
     *
     * @param id 省市区编号
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteDistrict(Long id) {
        District district = districtRepository.findById(id).get();
        district.setIsDel(true);
        district.setUpdateBy(1L);
        district.setUpdateAt(new Date());
        districtRepository.save(district);
    }

    /**
     * 功能描述 返回所有表中的省的信息
     *
     * @return java.util.List<java.lang.String>
     * @author Tanzujie
     * @date 2019-07-11
     */
    public List<String> getAllProvince() {
        List<String> provincesList = districtRepository.findProvinces();
        for (String a : provincesList) {
            log.info("Province : " + a);
        }
        return provincesList;
    }

    /**
     * 功能描述 通过省的字段返回所有的城市
     *
     * @param * @param province
     * @return java.util.List<java.lang.String>
     * @author Tanzujie
     * @date 2019-07-11
     */
    public List<String> getAllCityByProvince(String province) {
        val cities = new ArrayList<String>();
        List<District> districts = districtRepository.findDistinctByProvinceAndIsDel(province, false);
        for (District a : districts) {
            cities.add(a.getCity());
        }
        return cities;

    }

    /**
     * 根据省区分页查询省市区
     *
     * @param province   省份
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 省市区
     */
    public PageResult<DistrictVo> findDistrictByProvince(String province, Integer pageNumber, Integer pageSize) {
        Pageable page = PageRequest.of(pageNumber, pageSize);
        Page<District> districts = districtRepository.findByProvinceAndIsDel(province, false, page);
        return new PageResult<>(pageNumber, pageSize, districts.getTotalPages(), getDistrictVoList(districts));
    }

}
